package org.mtmi.ui.controls;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.mtmi.io.IControlIO;
import org.mtmi.io.controls.ValueControlledControlIO;
import org.mtmi.ui.GraphicUtil;
import org.mtmi.ui.M;
import org.mtmi.ui.controls.edits.LedBargraphControlEditor;
import org.mtmi.ui.edit.IControlEditor;
import org.mtmi.ui.layouts.LayoutData;
import org.mtmi.ui.scenes.CLR;
import org.mtmi.ui.scenes.COLOR;
import org.mtmi.ui.scenes.Scene;


public class LedBargraph extends AbstractValueControlledControl 
 implements IOrientable, ITouchableControl
{
	//note: the default range is 0..100 
	
	public LedBargraph(Scene scene, int _flags) {
		super(scene, _flags);
		setForeground( COLOR.grey70 );
		setBackground( COLOR.grey20 );
		setSize( computeSize(null) );
	}

	@Override
	public boolean isHorizontal() {
		return (getFlags() & M.VERTICAL)==0;
	}

	@Override
	public void setHorizontal( boolean horizontal ) {
		if( horizontal!=isHorizontal() ) {
			redraw(); //mark old bounds are to be redraw

			int w2 = size.x/2;
			int h2 = size.y/2;
			int cx = location.x+w2;
			int cy = location.y+h2;

			if( horizontal ) {
				flags &= ~M.VERTICAL; //reset flag
			} else {
				flags |= M.VERTICAL; //set flag
			}
			Point sz = computeSize( new LayoutData(getScene() ) );
			setBounds( cx-sz.x/2, cy-sz.y/2, sz.x, sz.y );
			redraw();
		}
	}
	
	@Override
	public Point computeSize(LayoutData l) {
		if( isHorizontal() ) {
			return new Point( 200, 30 );
		} else {
			return new Point( 30, 200 );
		}
	}
	
	@Override
	public boolean containsTouch(TouchControlEvent e) {
		return GraphicUtil.rectContains( location.x, location.y, size.x, size.y, e.x, e.y );
	}

	/** @return the led on color for value (in range 0..1) */ 
	protected Color getLedColor( float _value )
	{
		if( _value < 50 ) {
			return COLOR.green;
		} 
		else if( _value <= 75 ) {
			return COLOR.orange;
		}
		else {
			return COLOR.red;
		}
	}
	
	private static final int SZ = 10; //size of led
	private static final int SP = 5; //spacing between leds
	private static final int MG = 5; //margin around leds
	
	@Override
	public void paint( GC gc )
	{
		gc.setBackground( getBackground() );
		gc.fillRectangle( location.x, location.y, size.x, size.y );
		gc.setForeground( getForeground() );
		gc.setLineWidth( 2 );
		gc.drawRectangle( location.x+1, location.y+1, size.x-2, size.y-2 );
		
		int value = getValue();
		if( isHorizontal() ) {
			int wa = size.x-2*MG+SP;
			int nleds = wa/(SZ+SP);
			float sz = wa/(float)nleds;
			float x = location.x+MG;
			int y = location.y+MG;
			int w = (int)(sz-SP);
			int h = size.y-2*MG;
			for( int i=0; i<nleds; i++ ) {
				int v = Math.round( 100*(i+1)/(float)nleds );
System.out.println("led.v="+v);				
				Color c = getLedColor( v );
				if( v <= value ) {
					gc.setBackground( c );
					gc.fillRectangle( Math.round(x), y, w, h );
					//exemple rond:
					//int d = Math.min( w, h );
					//gc.fillOval( Math.round(x), y+(h-d)/2, d, d );
				} else {
					Color d = CLR.darker( c, 0.5f );
					gc.setBackground( d );
					gc.fillRectangle( Math.round(x), y, w, h );
					d.dispose();
				}
				x+=sz;
			}
		} else {
			int ha = size.y-2*MG+SP;
			int nleds = (int)( ha/(float)(SZ+SP) );
			float sz = ha/(float)nleds;
			int x = location.x+MG;
			int w = size.x-2*MG;
			int h = (int)( sz-SP );
			float y = location.y+size.y-MG-h;
			float hh = 2*MG+(SP+h)*nleds;
//int d = Math.min( w, h );
			for( int i=0; i<nleds; i++ ) {
				int v = Math.round( 100*(i+1)/(float)nleds );
				Color c = getLedColor( v );
				if( v <= value ) {
					gc.setBackground( c );
					gc.fillRectangle( x, Math.round(y), w, h );
					//exemple rond:
					//gc.fillOval( x+(w-d)/2, Math.round(y)+(h-d)/2, d, d );
				} else {
					Color dc = CLR.darker( c, 0.5f );
					gc.setBackground( dc );
					gc.fillRectangle( x, Math.round(y), w, h );
					//gc.fillOval( x+(w-d)/2, Math.round(y)+(h-d)/2, d, d );
					dc.dispose();
				}
				y-=sz;
			}
		}
	}

	@Override
	public Object getAdapter( Class<?> clazz, Object arg ) {
		if( clazz == IControlEditor.class ) {
			return new LedBargraphControlEditor( this );
		}
		if( clazz == IControlIO.class ) {
			return new ValueControlledControlIO();
		}
		return super.getAdapter( clazz, arg );
	}
}
